﻿using System;
using System.Linq;
using System.Windows.Forms;

namespace ProjectEuler.UI
{
    public partial class MainEulerUI : Form
    {
        private EulerThreadPool EulerThreadPool;

        public MainEulerUI()
        {
            InitializeComponent();
        }

        private void MainEulerUI_Load(object sender, EventArgs e)
        {
            listSolvedProblems.DataSource = ProblemLoader.FindAllProblems();
        }

        private void pictureEuler_DoubleClick(object sender, EventArgs e)
        {
            MessageBox.Show(EulerSays.GetRandomEulerSays(), "Euler says:");
        }

        private void btnSolutions_Click(object sender, EventArgs e)
        {
            InitializeProgress(listSolvedProblems.SelectedItems.Count);

            var problems = listSolvedProblems.SelectedItems.Cast<Problem>();

            timerProgress.Start();

            EulerThreadPool = new EulerThreadPool();

            foreach (var problem in problems)
            {
                EulerThreadPool.AddProblem(problem.ProblemInstance);
            }

            EulerThreadPool.StartSolving();
        }

        private void timerProgress_Tick(object sender, EventArgs e)
        {
            UpdateProgressBar();

            UpdateGridFromQueue();

            if (!EulerThreadPool.AnyThreadsStillRunning)
            {
                UpdateGridFromQueue();      // call again just to make sure the queue is cleared out

                CompleteProgress();
            }
        }

        private void InitializeProgress(int count)
        {
            gridResults.Rows.Clear();
            btnSolutions.Enabled = false;
            progressThreads.Visible = true;
            progressThreads.Maximum = count;
            progressThreads.Step = count;
            progressThreads.Value = 0;
        }

        private void UpdateProgressBar()
        {
            progressThreads.Value = EulerThreadPool.NumberProblemsSolvedSoFar;
        }

        private void UpdateGridFromQueue()
        {
            while(EulerThreadPool.AnySolvedProblemsInQueue)
            {
                var solvedProblem = EulerThreadPool.GetSolvedProblemFromQueue;
                gridResults.Rows.Add(solvedProblem.Number,
                                    solvedProblem.Description,
                                    solvedProblem.Answer,
                                    FormatRuntime(solvedProblem.Runtime));
            }
        }

        private static string FormatRuntime(TimeSpan timeSpan)
        {
            return timeSpan.ToString().Substring(3) + " s";
        }

        private void CompleteProgress()
        {
            timerProgress.Stop();
            btnSolutions.Enabled = true;
            progressThreads.Visible = false;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(
                @"2010, Matthew D. Groves\r\n
                  \r\n
                  Check out http://mgrovesprojecteuler.codeplex.com/ for more information and the latest version",
                "About");
        }
    }
}
